#include "tuya_os_adapt_bt.h"
#include "tuya_ws_db.h"
#include "InSdkCheckNetStatus.h"

#if CMAKE_SUPPORT_AB6012BX
#include "InSdkAB6012BX.h"
#endif

#define DEF_TAG "TYBle"

#if defined(TY_BT_MOD) && TY_BT_MOD == 1

/* add begin: by sunkz, interface regist */
static const TUYA_OS_BT_INTF m_tuya_os_bt_intfs = {
    .port_init = tuya_os_adapt_bt_port_init,
    .port_deinit = tuya_os_adapt_bt_port_deinit,
    .gap_disconnect = tuya_os_adapt_bt_gap_disconnect,
    .send = tuya_os_adapt_bt_send,
    .reset_adv = tuya_os_adapt_bt_reset_adv,
    .get_rssi = tuya_os_adapt_bt_get_rssi,
    .start_adv = tuya_os_adapt_bt_start_adv,
    .stop_adv = tuya_os_adapt_bt_stop_adv,
    .assign_scan = tuya_os_adapt_bt_assign_scan,
    .scan_init = NULL,
    .start_scan = tuya_os_adapt_bt_start_scan,
    .stop_scan = tuya_os_adapt_bt_stop_scan,
    .set_mac = tuya_ext_bt_setmac,
    .get_mac = tuya_ext_bt_getmac,
};
/* add end */

TY_BT_MSG_CB g_bt_msg_cb = NULL;
Com_s32 g_send_ble_buf_cnt = 0;

/***********************************************************
*************************function define********************
***********************************************************/
OPERATE_RET tuya_os_adapt_bt_port_init(ty_bt_param_t *p)
{
    if (p)
    {
        g_bt_msg_cb = p->cb;
    }

    return OPRT_OK;
}

OPERATE_RET tuya_os_adapt_bt_port_deinit(void)
{
    return OPRT_OK;
}

OPERATE_RET tuya_os_adapt_bt_gap_disconnect(void)
{
    return OPRT_OK;
}

#if CMAKE_SUPPORT_AB6012BX
void Sdk_BleRecv_App2Dev(char *data, int len)
{
    if (g_bt_msg_cb)
    {
        tuya_ble_data_buf_t ble_buf;
        ble_buf.data = (Com_pu8)data;
        ble_buf.len = len;
        g_bt_msg_cb(0, TY_BT_EVENT_RX_DATA, &ble_buf);
    }
}

void Sdk_BleRx_Status(int status)
{
    if (status == E_BLUE_STATUS_CONNECT)
    {
        tuya_ble_data_buf_t c_buf;
        memset(&c_buf, 0, sizeof(c_buf));
        g_bt_msg_cb(0, TY_BT_EVENT_CONNECTED, &c_buf);
    }
}

void *Sdk_BleInit_Thread(void *arg)
{
    JK_SetP2PMode(E_P2P_MODE_TY);
    JK_SetBlueRxCb(Sdk_BleRecv_App2Dev);
    JK_SetBlueStatusCb(Sdk_BleRx_Status);
    lib_ble_main();
    PRT_INFO(DEF_TAG,"ble init exit\n");
    pthread_exit(NULL);
}
#endif

OPERATE_RET tuya_os_adapt_bt_send(BYTE_T *data, UINT8_T len)
{
    if ((Ext_InSdkNetStatus_Check() == DEF_COM_FAILED) &&
        (Ext_InComFile_Access(DEF_FLAG_NO_NETWORK) == DEF_COM_FILE_EXIST))
    {
        if (data == NULL || len == 0)
        {
            return OPRT_INVALID_PARM;
        }

#if CMAKE_SUPPORT_AB6012BX
        gatt_svr_chr_notify((char *)data, len);
#endif
    }
    return OPRT_OK;
}

OPERATE_RET tuya_os_adapt_bt_reset_adv(tuya_ble_data_buf_t *adv, tuya_ble_data_buf_t *scan_resp)
{
    if ((Ext_InSdkNetStatus_Check() == DEF_COM_FAILED) &&
        (Ext_InComFile_Access(DEF_FLAG_NO_NETWORK) == DEF_COM_FILE_EXIST))
    {

#if CMAKE_SUPPORT_AB6012BX
        JK_ble_gap_adv_set(E_ADV_BROADCAST, adv->data, adv->len);
        JK_ble_gap_adv_set(E_ADV_RSP, scan_resp->data, scan_resp->len);
        static pthread_t blue_pthread = 0;

        if (blue_pthread == 0)
        {
            pthread_create(&blue_pthread, NULL, Sdk_BleInit_Thread, NULL);
            pthread_detach(blue_pthread);
        }
#endif

        if (g_bt_msg_cb)
        {
            tuya_ble_data_buf_t c_buf;

            memset(&c_buf, 0, sizeof(c_buf));
            g_bt_msg_cb(0, TY_BT_EVENT_DISCONNECTED, &c_buf);
        }
    }
    return OPRT_OS_ADAPTER_OK;
}

OPERATE_RET tuya_os_adapt_bt_get_rssi(SCHAR_T *rssi)
{
    return OPRT_OK;
}

OPERATE_RET tuya_os_adapt_bt_start_adv()
{
    PRT_INFO(DEF_TAG, "start adv\n");
    return OPRT_OK;
}

OPERATE_RET tuya_os_adapt_bt_stop_adv()
{
    PRT_INFO(DEF_TAG, "stop adv\n");
#if CMAKE_SUPPORT_AB6012BX
    JK_CloseBlue();
#endif
    return OPRT_OK;
}

OPERATE_RET tuya_os_adapt_bt_start_scan()
{
    return OPRT_OS_ADAPTER_BT_SCAN_FAILED;
}

OPERATE_RET tuya_os_adapt_bt_stop_scan()
{
    return OPRT_OS_ADAPTER_BT_SCAN_FAILED;
}

// 产测使用
OPERATE_RET tuya_os_adapt_bt_assign_scan(IN OUT ty_bt_scan_info_t *info)
{
    return OPRT_OK;
}

OPERATE_RET tuya_ext_bt_setmac(CONST NW_MAC_S *mac)
{
    OPERATE_RET ret = OPRT_OK;

    if (mac == NULL)
    {
        return OPRT_OS_ADAPTER_INVALID_PARM;
    }

    ret = wd_common_write(BT_MAC_ADDR_PARAM, mac->mac, TY_MAC_ADDR_LEN);
    if (ret < 0)
    {
        return OPRT_OS_ADAPTER_BT_INIT_FAILED;
    }

    PRT_DBG(DEF_TAG, "set mac %x:%x:%x:%x:%x:%x",
            mac->mac[0], mac->mac[1], mac->mac[2], mac->mac[3],
            mac->mac[4], mac->mac[5]);

    return OPRT_OS_ADAPTER_OK;
}

OPERATE_RET tuya_ext_bt_getmac(NW_MAC_S *mac)
{
    OPERATE_RET ret = OPRT_OK;
    BYTE_T *p_mac = NULL;
    UINT_T len = 0;

    if (mac == NULL)
    {
        return OPRT_OS_ADAPTER_INVALID_PARM;
    }

    ret = wd_common_read(BT_MAC_ADDR_PARAM, &p_mac, &len);
    if (ret < 0)
    {
        return OPRT_OS_ADAPTER_BT_INIT_FAILED;
    }

    memcpy(mac->mac, p_mac, TY_MAC_ADDR_LEN);
    PRT_DBG(DEF_TAG, "tuya_ext_bt_getmac %x:%x:%x:%x:%x:%x",
            mac->mac[0], mac->mac[1], mac->mac[2], mac->mac[3],
            mac->mac[4], mac->mac[5]);

    return OPRT_OS_ADAPTER_OK;
}

/* add begin: by sunkz, interface regist */
OPERATE_RET tuya_os_adapt_reg_bt_intf(void)
{
    return tuya_os_adapt_reg_intf(INTF_BT, (void *)&m_tuya_os_bt_intfs);
}
/* add end */
#endif
